'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.UAParser = undefined;

var _typeof2 = require('babel-runtime/helpers/typeof');

var _typeof3 = _interopRequireDefault(_typeof2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LIBVERSION = '0.7.18',
    EMPTY = '',
    UNKNOWN = '?',
    FUNC_TYPE = 'function',
    UNDEF_TYPE = 'undefined',
    OBJ_TYPE = 'object',
    STR_TYPE = 'string',
    MAJOR = 'major',
    MODEL = 'model',
    NAME = 'name',
    TYPE = 'type',
    VENDOR = 'vendor',
    VERSION = 'version',
    ARCHITECTURE = 'architecture',
    CONSOLE = 'console',
    MOBILE = 'mobile',
    TABLET = 'tablet',
    SMARTTV = 'smarttv',
    WEARABLE = 'wearable',
    EMBEDDED = 'embedded';

var util = {
    extend: function extend(regexes, extensions) {
        var margedRegexes = {};
        for (var i in regexes) {
            if (extensions[i] && extensions[i].length % 2 === 0) {
                margedRegexes[i] = extensions[i].concat(regexes[i]);
            } else {
                margedRegexes[i] = regexes[i];
            }
        }
        return margedRegexes;
    },
    has: function has(str1, str2) {
        if (typeof str1 === "string") {
            return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1;
        } else {
            return false;
        }
    },
    lowerize: function lowerize(str) {
        return str.toLowerCase();
    },
    major: function major(version) {
        return (typeof version === 'undefined' ? 'undefined' : (0, _typeof3.default)(version)) === STR_TYPE ? version.replace(/[^\d\.]/g, '').split(".")[0] : undefined;
    },
    trim: function trim(str) {
        return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
    }
};

var mapper = {

    rgx: function rgx(ua, arrays) {
        var i = 0,
            j,
            k,
            p,
            q,
            matches,
            match;
        while (i < arrays.length && !matches) {

            var regex = arrays[i],
                props = arrays[i + 1];
            j = k = 0;

            while (j < regex.length && !matches) {

                matches = regex[j++].exec(ua);

                if (!!matches) {
                    for (p = 0; p < props.length; p++) {
                        match = matches[++k];
                        q = props[p];

                        if ((typeof q === 'undefined' ? 'undefined' : (0, _typeof3.default)(q)) === OBJ_TYPE && q.length > 0) {
                            if (q.length == 2) {
                                if ((0, _typeof3.default)(q[1]) == FUNC_TYPE) {
                                    this[q[0]] = q[1].call(this, match);
                                } else {
                                    this[q[0]] = q[1];
                                }
                            } else if (q.length == 3) {
                                if ((0, _typeof3.default)(q[1]) === FUNC_TYPE && !(q[1].exec && q[1].test)) {
                                    this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
                                } else {
                                    this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
                                }
                            } else if (q.length == 4) {
                                this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
                            }
                        } else {
                            this[q] = match ? match : undefined;
                        }
                    }
                }
            }
            i += 2;
        }
    },

    str: function str(_str, map) {

        for (var i in map) {
            if ((0, _typeof3.default)(map[i]) === OBJ_TYPE && map[i].length > 0) {
                for (var j = 0; j < map[i].length; j++) {
                    if (util.has(map[i][j], _str)) {
                        return i === UNKNOWN ? undefined : i;
                    }
                }
            } else if (util.has(map[i], _str)) {
                return i === UNKNOWN ? undefined : i;
            }
        }
        return _str;
    }
};

var regexes = {

    browser: [],

    cpu: [],

    device: [],

    engine: [],

    os: []
};

var UAParser = exports.UAParser = function UAParser(uastring, extensions) {

    if ((typeof uastring === 'undefined' ? 'undefined' : (0, _typeof3.default)(uastring)) === 'object') {
        extensions = uastring;
        uastring = undefined;
    }

    if (!(this instanceof UAParser)) {
        return new UAParser(uastring, extensions).getResult();
    }

    var ua = uastring || (window && window.navigator && window.navigator.userAgent ? window.navigator.userAgent : EMPTY);
    var rgxmap = extensions ? util.extend(regexes, extensions) : regexes;


    this.getBrowser = function () {
        var browser = { name: undefined, version: undefined };
        mapper.rgx.call(browser, ua, rgxmap.browser);
        browser.major = util.major(browser.version);
        return browser;
    };
    this.getCPU = function () {
        var cpu = { architecture: undefined };
        mapper.rgx.call(cpu, ua, rgxmap.cpu);
        return cpu;
    };
    this.getDevice = function () {
        var device = { vendor: undefined, model: undefined, type: undefined };
        mapper.rgx.call(device, ua, rgxmap.device);
        return device;
    };
    this.getEngine = function () {
        var engine = { name: undefined, version: undefined };
        mapper.rgx.call(engine, ua, rgxmap.engine);
        return engine;
    };
    this.getOS = function () {
        var os = { name: undefined, version: undefined };
        mapper.rgx.call(os, ua, rgxmap.os);
        return os;
    };
    this.getResult = function () {
        return {
            ua: this.getUA(),
            browser: this.getBrowser(),
            engine: this.getEngine(),
            os: this.getOS(),
            device: this.getDevice(),
            cpu: this.getCPU()
        };
    };
    this.getUA = function () {
        return ua;
    };
    this.setUA = function (uastring) {
        ua = uastring;

        return this;
    };
    return this;
};

UAParser.VERSION = LIBVERSION;
UAParser.BROWSER = {
    NAME: NAME,
    MAJOR: MAJOR,
    VERSION: VERSION
};
UAParser.CPU = {
    ARCHITECTURE: ARCHITECTURE
};
UAParser.DEVICE = {
    MODEL: MODEL,
    VENDOR: VENDOR,
    TYPE: TYPE,
    CONSOLE: CONSOLE,
    MOBILE: MOBILE,
    SMARTTV: SMARTTV,
    TABLET: TABLET,
    WEARABLE: WEARABLE,
    EMBEDDED: EMBEDDED
};
UAParser.ENGINE = {
    NAME: NAME,
    VERSION: VERSION
};
UAParser.OS = {
    NAME: NAME,
    VERSION: VERSION
};

exports.default = UAParser;